
import pathVnode from './patchVnode.js';
import createElement from './createElemnet.js'

// 判断是否是同一个虚拟节点
function checkSameVnode(a,b) {
	return (a.sel == b.sel && a.key == b.key)
}
// 新前与旧前
// 新后与旧后
// 新后与旧前
// 新前与旧后
export default function updateChildren (parentElm,oldCh,newCh) {
	// 旧前
	let oldStartIdx =0;
	let oldStartVnode = oldCh[0];
	// 旧后
	let oldEndIdx =oldCh.length-1;
	let oldEndVnode = oldCh[oldEndIdx];
	// 新前
	let newStartIdx =0;
	let newStartVnode = newCh[0];
	// 新后
	let newEndIdx  = newCh.length-1;
	let newEndVnode = newCh[newEndIdx];console.log('初始时newENdVnode是：',newEndVnode)
	// 定义一个map
	let keymap = null;
	// 开始循环比较
	while(oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx){
		console.log("进入while循环中来了");
		//先进行判断掠过undefined或则null的标记项
		if(oldStartVnode==null || oldCh[oldStartIdx] == undefined ){
			oldStartVnode = oldCh[++ oldStartIdx];
			//console.log("111");
		}else if(oldEndVnode == null || oldCh[oldEndIdx] == undefined){
			oldEndVnode = oldCh[-- oldEndIdx];
			//console.log("222")
		}else if (newStartVnode == null || newCh[newStartIdx]== undefined) {
			newStartVnode = newCh[++newStartIdx];
			//console.log("333")
		}else if(newEndVnode ==null || newCh[newEndIdx] == undefined){
			newEndVnode = newCh[--newEndIdx];
			//console.log("444",newEndIdx)
		}else if(checkSameVnode(newStartVnode,oldStartVnode)){
			console.log("命中1");
			pathVnode(newStartVnode,oldStartVnode);
			oldStartVnode = oldCh[++oldStartIdx];
			newStartVnode = newCh[++newStartIdx];
		}else if(checkSameVnode(newEndVnode,oldEndVnode)){
			console.log('命中2');
			pathVnode(newEndVnode,oldEndVnode);
			newEndVnode = newCh[--newEndIdx];
			oldEndVnode = oldCh[--oldEndIdx];
		}else if(checkSameVnode(newEndVnode,oldStartVnode)){
			console.log('命中3');
			//当新后旧前命中时候，需要将新后这个节点移动到就后的后面。怎么移动这个节点？只要插入一个已经在dom树上的节点即可插入成功
			pathVnode(newEndVnode,oldStartVnode);
			parentElm.insertBefore(oldStartVnode.elm,oldStartVnode.elm.nextSibling);
			newEndVnode = newCh[--newEndIdx];
			oldStartVnode = oldCh[++ oldStartIdx];

		}else if(checkSameVnode(newStartVnode,oldEndVnode)){
			console.log('命中4');
			pathVnode(newStartVnode,oldEndVnode);
			//当新钱=前旧后命中时候，此时需要将旧后的节点移动到旧前的前面去
			parentElm.insertBefore(oldEndVnode.elm,oldSatrtVnode.elm);
			newStartVnode = newCh[++ newStartIdx];
			oldEndVnode = oldCh[-- oldEndIdx];

		}else{
			console.log("四种命中方式都没有命中");
			// 寻找key的map
			if (!keymap) {
				let keymap= {};
				for (var i = oldStart; i < oldEndIdx; i++) {
					const key = oldCh[i].key;
					if(key != undefined){
						keymap[key] = i;
					}
				}
			}
			console.log('此时的keymap是：',keymap);
			//寻找当前这项（newStartIdx）在keymap中的映射位置序号
			let idxInOld = keymap[newStartVnode.key];
			if(idxInOld == undefined){
				//此时，说明这是一个全新的项
				// 被加入的项（就是newStartVnode）此时不是一个真实的DOM
				parentElm.insertBefore(createElement(newSatrtVnode),oldSatrtVnode.elm)
			}else{
				//否则说明这不是一个新的项，而是一个需要移动的项
				const elmMoveTo = oldCh[idxInOld];
				pathVnode(elmMoveTo,newSatrtVnode);
				// 处理完成后将这项标记为undefined
				oldCh[idxInOld] = undefined;
				//调用insertBefore实现移动
				parentElm.insertBefore(elmMoveTo.elm,oldSatrtVnode.elm);
			}
			//指针下移动，只移动新的头
			newStartVnode = newCh[++newStartIdx];
		}
	};
	 console.log('没有进入while循环之中,增加节点和删除的两种情况');
	 //继续看看还有没有剩余，循环结束了start还是比old小
	 if (newStartIdx <= newEndIdx) {
	 	console.log('仍然有剩余节点是要加项，要把这些节点都插入到oldStartVnode前面');
	 	//遍历新的newCH，添加到老的没有处理的节点之前
	 	for(var i = newStartIdx;i<newEndIdx;i++){
	 		// insertBefore方法会自动识别null，如果是null就会自动插入到队尾去了，和appendChild方法功能一致
	 		//当前newCh[i]现在还不是DOM，需要调用careatElement()函数将它转换成dom节点
	 		parentElm.insertBefore(createElement(newCh[i]),oldSatrtVnode.elm)

	 	}
	 }else if(oldStartIdx<= oldEndIdx){
	 	console.log("old还有未处理的项，是要删除的项");
	 	// 批量删除oldstart和oldEnd指针中间的项目
	 	for(let i = oldStartIdx;i<oldEndIdx;i++){
	 		if(oldCh[i]){
	 			parentElm.removeChild(oldCh[i].elm);
	 		}
	 	}
	 }

}









